package com.admin.system.controller.exceptionHandler;

import com.admin.monmon.util.AjaxResponse;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * @author caixiaofeng
 * @version 1.0
 * @Description: <<全局异常捕获>>
 * @company 个人学习
 * @create 2020-11-04 10:30
 */
@Slf4j
@JsonInclude(JsonInclude.Include.NON_NULL)
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 统一异常处理方法
     *
     * @param response
     * @param e
     * @return
     */
    @ExceptionHandler(value = RuntimeException.class)
    public ResponseEntity<Object> globalExceptionHandler(HttpServletResponse response, RuntimeException e) {
        e.printStackTrace();
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(AjaxResponse.error(e.getMessage()));
    }

    /**
     * 空指针异常拦截
     *
     * @param response
     * @param e
     * @return
     */
    /*@ExceptionHandler(value = NullPointerException.class)
    public ResponseEntity<Object> nullPointerExceptionHandler(HttpServletResponse response, NullPointerException e) {
        e.printStackTrace();
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(AjaxResponse.error("空指针异常，请联系开发人员"));
    }*/

    /**
     * 身份验证异常拦截
     *
     * @param response
     * @param e
     * @return
     */
    @ExceptionHandler(value = AuthenticationException.class)
    public ResponseEntity<Object> authenticationExceptionHandler(HttpServletResponse response, AuthenticationException e) {
        e.printStackTrace();
        String message = e.getMessage();
        if (e instanceof BadCredentialsException) {
            message = "账户或密码错误";
        } else if (e instanceof CredentialsExpiredException) {
            message = "账户凭证已过期";
        } else if (e instanceof AccountExpiredException) {
            message = "账户已经过期，请修改密码";
        } else if (e instanceof LockedException) {
            message = "账户已被锁定";
        }
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(AjaxResponse.error(message));
    }


    /**
     * 参数异常拦截
     *
     * @param response
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ResponseEntity<Object> nullPointerExceptionHandler(HttpServletResponse response, MethodArgumentNotValidException e) {
        //返回使用参数校验错误信息
        //Map<String, String> collect = e.getBindingResult().getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage));
        String field = Objects.requireNonNull(e.getBindingResult().getFieldError()).getField();
        String defaultMessage = e.getBindingResult().getFieldError().getDefaultMessage();
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(AjaxResponse.error(field + ":" + defaultMessage));

        //返回第一个参数校验错误信息
        /*FieldError fieldError = e.getBindingResult().getFieldError();
        if (!ObjectUtils.isEmpty(fieldError)) {
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(fieldError.getField() + ":" + fieldError.getDefaultMessage());
        }
        e.printStackTrace();
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("");*/
    }

    /**
     * 未知异常
     * @param response
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseEntity<Object> exception(HttpServletResponse response, Exception e) {
        e.printStackTrace();
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(AjaxResponse.error(e.getMessage()));
    }
}
